/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * rulesPanel.java
 *
 * Created on 14.05.2009, 20:04:57
 */
package peripheral.designer.wizard;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import peripheral.logic.rule.DefaultRule;
import peripheral.logic.rule.Rule;
import peripheral.logic.symboladapter.SymbolAdapter;

/**
 *
 * @author Berni
 */
public class RulesRootPanel extends javax.swing.JPanel {

    private Window parent;
    public GridBagLayout layout;
    private JButton addRuleButton;
    private JButton addDefaultRuleButton;
    private SymbolAdapter symbolAdapter;
    private JPanel buttonPanel;
    private ArrayList<RulePanel> rulePanels;
    private List<JButton> removeButtons;
    
    //defines whether default rule is already set
    private boolean defaultRuleFlag;

    /** Creates new form rulesPanel */
    public RulesRootPanel(Window parent) {
        initComponents();

        this.parent = parent;

        layout = new GridBagLayout();

        this.setLayout(layout);

        buttonPanel = createButtonPanel();

        rulePanels = new ArrayList<RulePanel>();
        removeButtons = new ArrayList<JButton>();

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 597, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 380, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void setDefaultRuleEnabled(boolean flag) {
    	defaultRuleFlag = flag;
    	addDefaultRuleButton.setEnabled(flag);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
    public void setSymbolAdapter(SymbolAdapter symbolAdapter) {

    	setDefaultRuleEnabled(true);
    	
        this.symbolAdapter = symbolAdapter;

        rulePanels.clear();

        createRulePanels();

        if (symbolAdapter.getRules().size() == 0) {
            addNewRule(false);
        }

        this.windowChanged();
    }

    private void createRulePanels() {

    	int index = 1;
        for (Rule rule : symbolAdapter.getRules()) {

            RulePanel rulePanel = new RulePanel(rule, parent,index);
            rulePanels.add(rulePanel);

            //if there is already a defaultrule disable add
            if (rule instanceof DefaultRule) {
            	setDefaultRuleEnabled(false);
            }
            
            index++;
        }
    }

    private JPanel createButtonPanel() {
        JPanel localButtonPanel = new JPanel();
        localButtonPanel.setLayout(new java.awt.FlowLayout());

        addRuleButton = new JButton("Add Rule");
        addRuleButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

            	//create new usual rule
                addNewRule(false);

            }
        });
        
        addDefaultRuleButton = new JButton("Add Defaultrule");
        addDefaultRuleButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

            	//create new default rule
                addNewRule(true);

            }
        });

        localButtonPanel.setSize(250, 20);
        //addRuleButton.setSize(100, 20);
        //addDefaultRuleButton.setSize(120,20);
        localButtonPanel.add(addRuleButton);
        localButtonPanel.add(addDefaultRuleButton);

        return localButtonPanel;
    }

    /**
     * called every time a rulePanel is repainted
     */
    public void windowChanged() {

        this.removeAll();

        this.createLayout();

        this.validate();

        parent.validate();

        this.repaint();
    }

    private void createLayout() {

        int i = 0;

        GridBagConstraints gbc;

        this.removeButtons.clear();

        for (RulePanel rulePanel : rulePanels) {

            Dimension panelMinDim = rulePanel.getMinimumDisplaySize();

            gbc = makegbc(0, i * 3 + 1, 1, 3, GridBagConstraints.BOTH, (int) panelMinDim.getWidth(), (int) panelMinDim.getHeight());

            layout.setConstraints(rulePanel, gbc);

            this.add(rulePanel);

            //add button to remove
            final JButton removeButton = new JButton("Remove rule");
            this.removeButtons.add(removeButton);
            removeButton.addActionListener(
                    new ActionListener() {

                        public void actionPerformed(ActionEvent e) {
                            int index = removeButtons.indexOf(removeButton);
                            
                            removeRulePanel(rulePanels.get(index));  
                        }
                    });

            gbc = makegbc(1, i * 3 + 1, 1, 3, GridBagConstraints.NONE, removeButton.getWidth(), removeButton.getHeight());
            layout.setConstraints(removeButton, gbc);
            if (rulePanels.size() <= 1) {
                removeButton.setEnabled(false);
            }
            this.add(removeButton);

            i++;
        }

        //add button panel at least
        gbc = makegbc(0, i * 3 + 1, 1, 1, GridBagConstraints.NONE, (int) buttonPanel.getWidth(), (int) buttonPanel.getHeight());
        layout.setConstraints(buttonPanel, gbc);
        this.add(buttonPanel);

    }

    private void addNewRule(boolean defaultRule) {

    	Rule newRule= null;
    	
    	if (defaultRule) {
    		newRule = new DefaultRule(symbolAdapter);
    		this.setDefaultRuleEnabled(false);
    	}
    	else {
    		newRule = new Rule(symbolAdapter);
    	}

        symbolAdapter.getRules().add(newRule);

        RulePanel rulePanel = new RulePanel(newRule, parent,symbolAdapter.getRules().indexOf(newRule)+1);
        rulePanels.add(rulePanel);

        this.windowChanged();
    }

    public void removeRulePanel(RulePanel rulePanel) {

    	//update all indices of previous rulepanels in list
    	for (int i=rulePanels.indexOf(rulePanel); i <rulePanels.size() ; i++) {
    		rulePanels.get(i).setRuleIndex(i);
    	}
        rulePanels.remove(rulePanel);
        symbolAdapter.getRules().remove(rulePanel.getRule());
        
        if (rulePanel.getRule() instanceof DefaultRule) {
        	this.setDefaultRuleEnabled(true);
        }

        windowChanged();
    }

    /**
     * creates the settings for a component which should be displayed in GridBagLayout
     * @param x startcoordinate of component
     * @param y startcoordinate of component
     * @param width how many cells
     * @param height how many cells
     * @return
     */
    private GridBagConstraints makegbc(int x, int y, int width, int height, int fill, int ipadx, int ipady) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = width;
        gbc.gridheight = height;
        gbc.fill = fill;
        gbc.ipadx = ipadx;
        gbc.ipady = ipady;
        //Defines the border of each element
        gbc.insets = new Insets(10, 10, 10, 10);

        return gbc;
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        javax.swing.JFrame frame = new javax.swing.JFrame("TableRenderDemo");
        frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);


        //Create and set up the content pane.
        RulesRootPanel newContentPane = new RulesRootPanel(frame);
        newContentPane.setSymbolAdapter(new SymbolAdapter());
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(new JScrollPane(newContentPane));

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                createAndShowGUI();
            }
        });
    }
}
